package com.shrct.businessprocess.customerservice.impl;

import com.google.common.base.Objects;
import com.shrct.businessprocess.customerservice.RCContractInstallInfo;
import com.shrct.businessprocess.customerservice.RCContractInstallInfoStatus;
import com.shrct.businessprocess.customerservice.RCInstallProgressStatus;
import com.shrct.businessprocess.customerservice.RCRequireStatus;
import com.shrct.businessprocess.customerservice.RCServiceDocumentType;
import com.shrct.businessprocess.customerservice.RCServiceRecord;
import com.shrct.businessprocess.customerservice.impl.RCInstallProgressStatusImpl;
import com.shrct.businessprocess.customerservice.impl.RCServiceDocumentTypeImpl;
import com.shrct.businessprocess.customerservice.impl.RCServiceRecordImpl;
import com.shrct.businessprocess.customerservice.proxy.RCContractInstallInfoProxy;
import com.shrct.businessprocess.product.RCBrand;
import com.shrct.businessprocess.product.impl.RCBrandImpl;
import edu.fudan.langlab.domain.statemachine.ModelObjectLogService;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IGenericQuery;
import edu.fudan.mylang.pf.IObjectFactory;
import java.util.Collection;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;

@Entity
@DiscriminatorValue("RCCONTRACTINSTALLINFO_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "rccontractinstallinfo")
public class RCContractInstallInfoImpl extends BaseModelObject implements RCContractInstallInfo {
  public RCContractInstallInfoImpl() {
    super();
  }
  
  private RCContractInstallInfoStatus Status;
  
  public RCContractInstallInfoStatus getStatus() {
    return this.Status;
  }
  
  private ModelObjectLogService getModelObjectLogService() {
    return getBeanFactory().getBean(ModelObjectLogService.class);
  }
  
  private void _start() {
    
    this.requireInstall = RCRequireStatus.unknown;
    Status=RCContractInstallInfoStatus.waiting4Initialize;
  }
  
  public void start() {
    if(Status==null){
    	_start();
    	getModelObjectLogService().createLog(this,"Status","Start");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCContractInstallInfoEventsManager.class).fireStarted(this);					
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException("allready started");
    }
  }
  
  private void _setAsRequired() {
    
    this.requireInstall = RCRequireStatus.required;
    Status=RCContractInstallInfoStatus.executing;
  }
  
  public void setAsRequired() {
    if(Status==RCContractInstallInfoStatus.waiting4Initialize||Status==RCContractInstallInfoStatus.notRequired){
    	_setAsRequired();
    	getModelObjectLogService().createLog(this,"Status","setAsRequired");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCContractInstallInfoEventsManager.class).fireSetAsRequired(this);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _setAsNotRequired() {
    
    this.requireInstall = RCRequireStatus.notRequired;
    Status=RCContractInstallInfoStatus.notRequired;
  }
  
  public void setAsNotRequired() {
    if(Status==RCContractInstallInfoStatus.waiting4Initialize){
    	_setAsNotRequired();
    	getModelObjectLogService().createLog(this,"Status","setAsNotRequired");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCContractInstallInfoEventsManager.class).fireSetAsNotRequired(this);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _cancel() {
    
    this.requireInstall = RCRequireStatus.unknown;
    this.removeAllServiceRecords();
    Status=RCContractInstallInfoStatus.waiting4Initialize;
  }
  
  public void cancel() {
    if(Status==RCContractInstallInfoStatus.notRequired||Status==RCContractInstallInfoStatus.executing){
    	_cancel();
    	getModelObjectLogService().createLog(this,"Status","cancel");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCContractInstallInfoEventsManager.class).fireCancel(this);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _updateInfo(final Procedure1<? super RCContractInstallInfo> preInit) {
    
    preInit.apply(this);
  }
  
  public void updateInfo(final Procedure1<? super RCContractInstallInfo> preInit) {
    if(Status==RCContractInstallInfoStatus.executing){
    	_updateInfo(preInit);
    	getModelObjectLogService().createLog(this,"Status","updateInfo");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCContractInstallInfoEventsManager.class).fireUpdateInfo(this,preInit);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _finish(final Date finishDate) {
    
    RCInstallProgressStatus _finishStatus = this.getFinishStatus();
    this.installProgress = _finishStatus;
    this.installFinishDate = finishDate;
    Status=RCContractInstallInfoStatus.finished;
  }
  
  public void finish(final Date finishDate) {
    if(Status==RCContractInstallInfoStatus.executing){
    	_finish(finishDate);
    	getModelObjectLogService().createLog(this,"Status","finish");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCContractInstallInfoEventsManager.class).fireFinish(this,finishDate);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _sendMessage() {
    
  }
  
  public void sendMessage() {
    if(Status==RCContractInstallInfoStatus.executing){
    	_sendMessage();
    	getModelObjectLogService().createLog(this,"Status","sendMessage");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCContractInstallInfoEventsManager.class).fireSendMessage(this);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _doAddtoServiceRecords(final RCServiceRecord serviceRecord) {
    
    boolean _contains = this.serviceRecords.contains(serviceRecord);
    boolean _not = (!_contains);
    if (_not) {
      this.addtoServiceRecords(serviceRecord);
    }
  }
  
  public void doAddtoServiceRecords(final RCServiceRecord serviceRecord) {
    if(Status==RCContractInstallInfoStatus.executing||Status==RCContractInstallInfoStatus.finished){
    	_doAddtoServiceRecords(serviceRecord);
    	getModelObjectLogService().createLog(this,"Status","doAddtoServiceRecords");
    	getBeanFactory().getBean(com.shrct.businessprocess.customerservice.events.RCContractInstallInfoEventsManager.class).fireDoAddtoServiceRecords(this,serviceRecord);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  public Boolean isWaiting4Initialize() {
    return com.shrct.businessprocess.customerservice.RCContractInstallInfoStatus.waiting4Initialize==Status;
  }
  
  public Boolean isNotRequired() {
    return com.shrct.businessprocess.customerservice.RCContractInstallInfoStatus.notRequired==Status;
  }
  
  public Boolean isExecuting() {
    return com.shrct.businessprocess.customerservice.RCContractInstallInfoStatus.executing==Status;
  }
  
  public Boolean isFinished() {
    return com.shrct.businessprocess.customerservice.RCContractInstallInfoStatus.finished==Status;
  }
  
  private RCRequireStatus requireInstall = RCRequireStatus.unknown;
  
  public RCRequireStatus getRequireInstall() {
    return this.requireInstall;
  }
  
  public RCContractInstallInfo setRequireInstall(final RCRequireStatus requireInstall) {
    this.requireInstall = requireInstall;
    return this;			
    
  }
  
  @JoinColumn(name = "installProgress_id")
  @ManyToOne(targetEntity = RCInstallProgressStatusImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCInstallProgressStatus installProgress;
  
  public RCInstallProgressStatus getInstallProgress() {
    return this.installProgress;
  }
  
  public RCContractInstallInfo setInstallProgress(final RCInstallProgressStatus installProgress) {
    this.installProgress = installProgress;
    return this;			
    
  }
  
  private String installLocation;
  
  public String getInstallLocation() {
    return this.installLocation;
  }
  
  public RCContractInstallInfo setInstallLocation(final String installLocation) {
    this.installLocation = installLocation;
    return this;			
    
  }
  
  private Date installDate;
  
  public Date getInstallDate() {
    return this.installDate;
  }
  
  public RCContractInstallInfo setInstallDate(final Date installDate) {
    this.installDate = installDate;
    return this;			
    
  }
  
  private Integer installDays;
  
  public Integer getInstallDays() {
    return this.installDays;
  }
  
  public RCContractInstallInfo setInstallDays(final Integer installDays) {
    this.installDays = installDays;
    return this;			
    
  }
  
  private Boolean isFinished = Boolean.valueOf(false);
  
  public Boolean getIsFinished() {
    return this.isFinished;
  }
  
  public RCContractInstallInfo setIsFinished(final Boolean isFinished) {
    this.isFinished = isFinished;
    return this;			
    
  }
  
  private Date installFinishDate;
  
  public Date getInstallFinishDate() {
    return this.installFinishDate;
  }
  
  public RCContractInstallInfo setInstallFinishDate(final Date installFinishDate) {
    this.installFinishDate = installFinishDate;
    return this;			
    
  }
  
  @JoinColumn(name = "brand_id")
  @ManyToOne(targetEntity = RCBrandImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCBrand brand;
  
  public RCBrand getBrand() {
    return this.brand;
  }
  
  public RCContractInstallInfo setBrand(final RCBrand brand) {
    this.brand = brand;
    return this;			
    
  }
  
  @ManyToMany(targetEntity = RCServiceDocumentTypeImpl.class)
  @JoinTable(name = "m2m_rccontractinstallinfo_documentsrequired", joinColumns = @JoinColumn(name = "rccontractinstallinfo_id") , inverseJoinColumns = @JoinColumn(name = "rCServiceDocumentType_inv_id") )
  private Collection<RCServiceDocumentType> documentsRequired = new java.util.ArrayList<com.shrct.businessprocess.customerservice.RCServiceDocumentType>();;
  
  public Collection<RCServiceDocumentType> getDocumentsRequired() {
    return this.documentsRequired;
  }
  
  public RCContractInstallInfo setDocumentsRequired(final Iterable<RCServiceDocumentType> documentsRequired) {
    removeAllDocumentsRequired();
    for(RCServiceDocumentType ca : documentsRequired){
    	addtoDocumentsRequired(ca);
    }
    return this;		
    
  }
  
  public RCContractInstallInfo addtoDocumentsRequired(final RCServiceDocumentType rCServiceDocumentType) {
    this.documentsRequired.add(rCServiceDocumentType);
    return this;
    
  }
  
  public RCContractInstallInfo removeAllDocumentsRequired() {
    this.documentsRequired.clear();
    return this;	
    
  }
  
  public RCContractInstallInfo removeFromDocumentsRequired(final RCServiceDocumentType rCServiceDocumentType) {
    this.documentsRequired.remove(rCServiceDocumentType);
    return this;
    
  }
  
  @ManyToMany(targetEntity = RCServiceDocumentTypeImpl.class)
  @JoinTable(name = "m2m_rccontractinstallinfo_documentssubmitted", joinColumns = @JoinColumn(name = "rccontractinstallinfo_id") , inverseJoinColumns = @JoinColumn(name = "rCServiceDocumentType_inv_id") )
  private Collection<RCServiceDocumentType> documentsSubmitted = new java.util.ArrayList<com.shrct.businessprocess.customerservice.RCServiceDocumentType>();;
  
  public Collection<RCServiceDocumentType> getDocumentsSubmitted() {
    return this.documentsSubmitted;
  }
  
  public RCContractInstallInfo setDocumentsSubmitted(final Iterable<RCServiceDocumentType> documentsSubmitted) {
    removeAllDocumentsSubmitted();
    for(RCServiceDocumentType ca : documentsSubmitted){
    	addtoDocumentsSubmitted(ca);
    }
    return this;		
    
  }
  
  public RCContractInstallInfo addtoDocumentsSubmitted(final RCServiceDocumentType rCServiceDocumentType) {
    this.documentsSubmitted.add(rCServiceDocumentType);
    return this;
    
  }
  
  public RCContractInstallInfo removeAllDocumentsSubmitted() {
    this.documentsSubmitted.clear();
    return this;	
    
  }
  
  public RCContractInstallInfo removeFromDocumentsSubmitted(final RCServiceDocumentType rCServiceDocumentType) {
    this.documentsSubmitted.remove(rCServiceDocumentType);
    return this;
    
  }
  
  @ManyToMany(targetEntity = RCServiceRecordImpl.class)
  @JoinTable(name = "m2m_rccontractinstallinfo_servicerecords", joinColumns = @JoinColumn(name = "rccontractinstallinfo_id") , inverseJoinColumns = @JoinColumn(name = "rCServiceRecord_inv_id") )
  private Collection<RCServiceRecord> serviceRecords = new java.util.ArrayList<com.shrct.businessprocess.customerservice.RCServiceRecord>();;
  
  public Collection<RCServiceRecord> getServiceRecords() {
    return this.serviceRecords;
  }
  
  public RCContractInstallInfo setServiceRecords(final Iterable<RCServiceRecord> serviceRecords) {
    removeAllServiceRecords();
    for(RCServiceRecord ca : serviceRecords){
    	addtoServiceRecords(ca);
    }
    return this;		
    
  }
  
  public RCContractInstallInfo addtoServiceRecords(final RCServiceRecord rCServiceRecord) {
    this.serviceRecords.add(rCServiceRecord);
    return this;
    
  }
  
  public RCContractInstallInfo removeAllServiceRecords() {
    this.serviceRecords.clear();
    return this;	
    
  }
  
  public RCContractInstallInfo removeFromServiceRecords(final RCServiceRecord rCServiceRecord) {
    this.serviceRecords.remove(rCServiceRecord);
    return this;
    
  }
  
  private String comment;
  
  public String getComment() {
    return this.comment;
  }
  
  public RCContractInstallInfo setComment(final String comment) {
    this.comment = comment;
    return this;			
    
  }
  
  public RCInstallProgressStatus getFinishStatus() {
    RCInstallProgressStatus _xblockexpression = null;
    {
      final String finishCodeId = "_001";
      IGenericQuery<RCInstallProgressStatus> query=getObjectFactory().createGenericQuery(RCInstallProgressStatus.class,"select e from com.shrct.businessprocess.customerservice.impl.RCInstallProgressStatusImpl as e   where ((e.codeid) = (:finishCodeId)) and  e.active = 1      ").setParameter("finishCodeId",finishCodeId);
      RCInstallProgressStatus _uniqueResult = query.uniqueResult();
      _xblockexpression = (_uniqueResult);
    }
    return _xblockexpression;
  }
  
  public Boolean isFinish() {
    RCInstallProgressStatus _finishStatus = this.getFinishStatus();
    boolean _equals = Objects.equal(this.installProgress, _finishStatus);
    return Boolean.valueOf(_equals);
  }
  
  public static RCContractInstallInfo create(final IObjectFactory objectFactory) {
    com.shrct.businessprocess.customerservice.RCContractInstallInfo rCContractInstallInfo = new com.shrct.businessprocess.customerservice.impl.RCContractInstallInfoImpl(
    );
    objectFactory.create(rCContractInstallInfo);
    return rCContractInstallInfo;			
    
  }
  
  public static RCContractInstallInfo createRCContractInstallInfoImpl(final IObjectFactory objectFactory, final Procedure1<RCContractInstallInfo> init) {
    com.shrct.businessprocess.customerservice.RCContractInstallInfo rCContractInstallInfo = new com.shrct.businessprocess.customerservice.impl.RCContractInstallInfoImpl(
    );
    objectFactory.create(rCContractInstallInfo);
    init.apply(rCContractInstallInfo);
    
    return rCContractInstallInfo;			
    
  }
  
  public RCContractInstallInfoProxy toProxy() {
    com.shrct.businessprocess.customerservice.proxy.RCContractInstallInfoProxy proxy = new com.shrct.businessprocess.customerservice.proxy.RCContractInstallInfoProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    proxy.setStatus(this.getStatus().name());
    return proxy;
    
  }
}
